home *** CD-ROM | disk | FTP | other *** search
/ MacFormat 1995 January / macformat-020.iso / Shareware City / Developers / Synthesizer Source / Synthesizer Folder / LFOGenerator.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-10-01  |  43.1 KB  |  1,436 lines  |  [TEXT/KAHL]

  1. /* LFOGenerator.c */
  2. /*****************************************************************************/
  3. /*                                                                           */
  4. /*    Synthesizer:  Digital Music Synthesis on General Purpose Computers     */
  5. /*    Copyright (C) 1994  Thomas R. Lawrence                                 */
  6. /*                                                                           */
  7. /*    This program is free software; you can redistribute it and/or modify   */
  8. /*    it under the terms of the GNU General Public License as published by   */
  9. /*    the Free Software Foundation; either version 2 of the License, or      */
  10. /*    (at your option) any later version.                                    */
  11. /*                                                                           */
  12. /*    This program is distributed in the hope that it will be useful,        */
  13. /*    but WITHOUT ANY WARRANTY; without even the implied warranty of         */
  14. /*    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the          */
  15. /*    GNU General Public License for more details.                           */
  16. /*                                                                           */
  17. /*    You should have received a copy of the GNU General Public License      */
  18. /*    along with this program; if not, write to the Free Software            */
  19. /*    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.              */
  20. /*                                                                           */
  21. /*    Thomas R. Lawrence can be reached at tomlaw@world.std.com.             */
  22. /*                                                                           */
  23. /*****************************************************************************/
  24.  
  25. #include "MiscInfo.h"
  26. #include "Audit.h"
  27. #include "Debug.h"
  28. #include "Definitions.h"
  29.  
  30. #include "LFOGenerator.h"
  31. #include "Memory.h"
  32. #include "EnvelopeState.h"
  33. #include "LFOSpecifier.h"
  34. #include "LFOListSpecifier.h"
  35. #include "FloatingPoint.h"
  36. #include "RandomNumbers.h"
  37. #include "Frequency.h"
  38. #include "Multisampler.h"
  39. #include "64BitMath.h"
  40. #include "SampleConsts.h"
  41.  
  42.  
  43. #define TWOPI ((float)6.28318530717958648)
  44.  
  45.  
  46. static long                                RandomSeed = PARKANDMILLERMINIMUM;
  47.  
  48.  
  49. typedef struct LFOOneStateRec
  50.     {
  51.         /* pointer to the LFO generating function */
  52.         float                                        (*GenFunction)(struct LFOOneStateRec* State, float Phase,
  53.                                                             float OriginalValue, float Amplitude);
  54.  
  55.         /* phase index counter */
  56.         FastFixedType                        CurrentPhase;
  57.  
  58.         /* the envelope controlling the amplitude. */
  59.         EvalEnvelopeRec*                LFOAmplitudeEnvelope;
  60.         /* the envelope controlling the frequency.  the value from here is periods per second */
  61.         EvalEnvelopeRec*                LFOFrequencyEnvelope;
  62.  
  63.         /* if this is True, then modulation is linear, otherwise modulation is */
  64.         /* exponential */
  65.         MyBoolean                                ModulateLinear;
  66.  
  67.         /* what kind of operator are we using */
  68.         LFOOscTypes                            Operator;
  69.  
  70.         /* source information for the wave table */
  71.         MultiSampleRec*                    WaveTableSourceSelector;
  72.  
  73.         /* this is true if the wave table was defined */
  74.         MyBoolean                                WaveTableWasDefined;
  75.         /* number of frames per table */
  76.         long                                        FramesPerTable;
  77.         /* number of tables */
  78.         long                                        NumberOfTables;
  79.         /* raw wave table data array */
  80.         void**                                    WaveTableMatrix;
  81.         /* number of bits in the data for the table */
  82.         NumBitsType                            TableNumBits;
  83.         /* envelope controlling wave table index */
  84.         EvalEnvelopeRec*                WaveTableIndexEnvelope;
  85.  
  86.         /* link to the next one */
  87.         struct LFOOneStateRec*    Next;
  88.     } LFOOneStateRec;
  89.  
  90.  
  91. struct LFOGenRec
  92.     {
  93.         /* list of single LFO entries, which we sum up. */
  94.         LFOOneStateRec*                    LFOList;
  95.  
  96.         /* this is the correction factor from LFOFrequencyEnvelope which converts */
  97.         /* it from periods per second into an interval we can add to CurrentPhase */
  98.         FastFixedType                        CorrectionFactor;
  99.  
  100.         /* number of envelope clock pulses per second */
  101.         float                                        EnvelopeTicksPerSecond;
  102.  
  103.         /* link for caching records */
  104.         LFOGenRec*                            GarbageLink;
  105.     };
  106.  
  107.  
  108. /* prototypes */
  109. static float                        AddConst(LFOOneStateRec* State, float Phase,
  110.                                                     float OriginalValue, float Amplitude);
  111. static float                        AddSignSine(LFOOneStateRec* State, float Phase,
  112.                                                     float OriginalValue, float Amplitude);
  113. static float                        AddPosSine(LFOOneStateRec* State, float Phase,
  114.                                                     float OriginalValue, float Amplitude);
  115. static float                        AddSignTriangle(LFOOneStateRec* State, float Phase,
  116.                                                     float OriginalValue, float Amplitude);
  117. static float                        AddPosTriangle(LFOOneStateRec* State, float Phase,
  118.                                                     float OriginalValue, float Amplitude);
  119. static float                        AddSignSquare(LFOOneStateRec* State, float Phase,
  120.                                                     float OriginalValue, float Amplitude);
  121. static float                        AddPosSquare(LFOOneStateRec* State, float Phase,
  122.                                                     float OriginalValue, float Amplitude);
  123. static float                        AddSignRamp(LFOOneStateRec* State, float Phase,
  124.                                                     float OriginalValue, float Amplitude);
  125. static float                        AddPosRamp(LFOOneStateRec* State, float Phase,
  126.                                                     float OriginalValue, float Amplitude);
  127. static float                        AddSignFuzz(LFOOneStateRec* State, float Phase,
  128.                                                     float OriginalValue, float Amplitude);
  129. static float                        AddPosFuzz(LFOOneStateRec* State, float Phase,
  130.                                                     float OriginalValue, float Amplitude);
  131. static float                        AddWaveTable(LFOOneStateRec* State, float Phase,
  132.                                                     float OriginalValue, float Amplitude);
  133. static float                        MultConst(LFOOneStateRec* State, float Phase,
  134.                                                     float OriginalValue, float Amplitude);
  135. static float                        MultSignSine(LFOOneStateRec* State, float Phase,
  136.                                                     float OriginalValue, float Amplitude);
  137. static float                        MultPosSine(LFOOneStateRec* State, float Phase,
  138.                                                     float OriginalValue, float Amplitude);
  139. static float                        MultSignTriangle(LFOOneStateRec* State, float Phase,
  140.                                                     float OriginalValue, float Amplitude);
  141. static float                        MultPosTriangle(LFOOneStateRec* State, float Phase,
  142.                                                     float OriginalValue, float Amplitude);
  143. static float                        MultSignSquare(LFOOneStateRec* State, float Phase,
  144.                                                     float OriginalValue, float Amplitude);
  145. static float                        MultPosSquare(LFOOneStateRec* State, float Phase,
  146.                                                     float OriginalValue, float Amplitude);
  147. static float                        MultSignRamp(LFOOneStateRec* State, float Phase,
  148.                                                     float OriginalValue, float Amplitude);
  149. static float                        MultPosRamp(LFOOneStateRec* State, float Phase,
  150.                                                     float OriginalValue, float Amplitude);
  151. static float                        MultSignFuzz(LFOOneStateRec* State, float Phase,
  152.                                                     float OriginalValue, float Amplitude);
  153. static float                        MultPosFuzz(LFOOneStateRec* State, float Phase,
  154.                                                     float OriginalValue, float Amplitude);
  155. static float                        MultWaveTable(LFOOneStateRec* State, float Phase,
  156.                                                     float OriginalValue, float Amplitude);
  157. static float                        InvMultConst(LFOOneStateRec* State, float Phase,
  158.                                                     float OriginalValue, float Amplitude);
  159. static float                        InvMultSignSine(LFOOneStateRec* State, float Phase,
  160.                                                     float OriginalValue, float Amplitude);
  161. static float                        InvMultPosSine(LFOOneStateRec* State, float Phase,
  162.                                                     float OriginalValue, float Amplitude);
  163. static float                        InvMultSignTriangle(LFOOneStateRec* State, float Phase,
  164.                                                     float OriginalValue, float Amplitude);
  165. static float                        InvMultPosTriangle(LFOOneStateRec* State, float Phase,
  166.                                                     float OriginalValue, float Amplitude);
  167. static float                        InvMultSignSquare(LFOOneStateRec* State, float Phase,
  168.                                                     float OriginalValue, float Amplitude);
  169. static float                        InvMultPosSquare(LFOOneStateRec* State, float Phase,
  170.                                                     float OriginalValue, float Amplitude);
  171. static float                        InvMultSignRamp(LFOOneStateRec* State, float Phase,
  172.                                                     float OriginalValue, float Amplitude);
  173. static float                        InvMultPosRamp(LFOOneStateRec* State, float Phase,
  174.                                                     float OriginalValue, float Amplitude);
  175. static float                        InvMultSignFuzz(LFOOneStateRec* State, float Phase,
  176.                                                     float OriginalValue, float Amplitude);
  177. static float                        InvMultPosFuzz(LFOOneStateRec* State, float Phase,
  178.                                                     float OriginalValue, float Amplitude);
  179. static float                        InvMultWaveTable(LFOOneStateRec* State, float Phase,
  180.                                                     float OriginalValue, float Amplitude);
  181.  
  182.  
  183. static LFOGenRec*                    LFOGenFreeList = NIL;
  184. static LFOOneStateRec*        LFOOneStateFreeList = NIL;
  185.  
  186.  
  187. /* flush cached LFO generator records */
  188. void                                FlushLFOGeneratorRecords(void)
  189.     {
  190.         while (LFOGenFreeList != NIL)
  191.             {
  192.                 LFOGenRec*                Temp;
  193.  
  194.                 Temp = LFOGenFreeList;
  195.                 LFOGenFreeList = LFOGenFreeList->GarbageLink;
  196.                 ReleasePtr((char*)Temp);
  197.             }
  198.  
  199.         while (LFOOneStateFreeList != NIL)
  200.             {
  201.                 LFOOneStateRec*        Temp;
  202.  
  203.                 Temp = LFOOneStateFreeList;
  204.                 LFOOneStateFreeList = LFOOneStateFreeList->Next;
  205.                 ReleasePtr((char*)Temp);
  206.             }
  207.     }
  208.  
  209.  
  210. #if DEBUG
  211. static void                    ValidateLFOGen(LFOGenRec* LFOGen)
  212.     {
  213.         LFOGenRec*                Scan;
  214.  
  215.         Scan = LFOGenFreeList;
  216.         while (Scan != NIL)
  217.             {
  218.                 if (Scan == LFOGen)
  219.                     {
  220.                         PRERR(ForceAbort,"ValidateLFOGen:  it's on the free list");
  221.                     }
  222.                 Scan = Scan->GarbageLink;
  223.             }
  224.     }
  225. #else
  226. #define ValidateLFOGen(x) ((void)0)
  227. #endif
  228.  
  229.  
  230. #if DEBUG
  231. static void                    ValidateLFOOneState(LFOOneStateRec* OneState)
  232.     {
  233.         LFOOneStateRec*        Scan;
  234.  
  235.         Scan = LFOOneStateFreeList;
  236.         while (Scan != NIL)
  237.             {
  238.                 if (Scan == OneState)
  239.                     {
  240.                         PRERR(ForceAbort,"ValidateLFOOneState:  it's on the free list");
  241.                     }
  242.                 Scan = Scan->Next;
  243.             }
  244.     }
  245. #else
  246. #define ValidateLFOOneState(x) ((void)0)
  247. #endif
  248.  
  249.  
  250. /* create a new LFO generator based on a list of specifications */
  251. /* it returns the largest pre-origin time for all of the envelopes it contains */
  252. /* The volume scaling factor is specified so that additive tremolo effects */
  253. /* are scaled properly */
  254. LFOGenRec*                    NewLFOGenerator(struct LFOListSpecRec* LFOListSpec,
  255.                                             long* MaxPreOriginTime, float Accent1, float Accent2,
  256.                                             float Accent3, float Accent4, float FrequencyHertz,
  257.                                             float HurryUp, float TicksPerSecond, float AmplitudeScaling,
  258.                                             float FrequencyScaling, LFOArithSelect ModulationMode,
  259.                                             float VolumeScalingFactor, float FreqForMultisampling)
  260.     {
  261.         LFOGenRec*                LFOGen;
  262.         long                            ListLimit;
  263.         long                            ListScan;
  264.         LFOOneStateRec*        ListTail;
  265.         long                            MaxPreOrigin;
  266.  
  267.         CheckPtrExistence(LFOListSpec);
  268.         if (LFOGenFreeList != NIL)
  269.             {
  270.                 LFOGen = LFOGenFreeList;
  271.                 LFOGenFreeList = LFOGenFreeList->GarbageLink;
  272.             }
  273.          else
  274.             {
  275.                 LFOGen = (LFOGenRec*)AllocPtrCanFail(sizeof(LFOGenRec),"LFOGenRec");
  276.                 if (LFOGen == NIL)
  277.                     {
  278.                         return NIL;
  279.                     }
  280.             }
  281.  
  282.         /* calculate correction factor.  when this factor is multiplied by some */
  283.         /* thing in periods/second, it converts it to periods/update */
  284.         LFOGen->CorrectionFactor = Double2FastFixed(1 / TicksPerSecond);
  285.  
  286.         /* remember the envelope rate */
  287.         LFOGen->EnvelopeTicksPerSecond = TicksPerSecond;
  288.  
  289.         /* build the list of thingers */
  290.         LFOGen->LFOList = NIL;
  291.         ListTail = NIL;
  292.         ListLimit = LFOListSpecGetNumElements(LFOListSpec);
  293.         MaxPreOrigin = 0;
  294.         for (ListScan = 0; ListScan < ListLimit; ListScan += 1)
  295.             {
  296.                 LFOSpecRec*                OneLFOSpec;
  297.                 LFOOneStateRec*        ListNode;
  298.                 long                            PreOriginTime;
  299.                 float                            AmplitudeFactor;
  300.  
  301.                 /* allocate an entry */
  302.                 if (LFOOneStateFreeList != NIL)
  303.                     {
  304.                         ListNode = LFOOneStateFreeList;
  305.                         LFOOneStateFreeList = LFOOneStateFreeList->Next;
  306.                     }
  307.                  else
  308.                     {
  309.                         ListNode = (LFOOneStateRec*)AllocPtrCanFail(sizeof(LFOOneStateRec),
  310.                             "LFOOneStateRec");
  311.                         if (ListNode == NIL)
  312.                             {
  313.                              FailurePoint1:
  314.                                 while (LFOGen->LFOList != NIL)
  315.                                     {
  316.                                         ListNode = LFOGen->LFOList;
  317.                                         LFOGen->LFOList = LFOGen->LFOList->Next;
  318.                                         DisposeEnvelopeStateRecord(ListNode->LFOAmplitudeEnvelope);
  319.                                         DisposeEnvelopeStateRecord(ListNode->LFOFrequencyEnvelope);
  320.                                         ListNode->Next = LFOOneStateFreeList;
  321.                                         LFOOneStateFreeList = ListNode;
  322.                                     }
  323.                                 LFOGen->GarbageLink = LFOGenFreeList;
  324.                                 LFOGenFreeList = LFOGen;
  325.                                 return NIL;
  326.                             }
  327.                     }
  328.                 /* initialize phase index */
  329.                 ListNode->CurrentPhase = 0;
  330.                 /* get the data to put in it */
  331.                 OneLFOSpec = LFOListSpecGetLFOSpec(LFOListSpec,ListScan);
  332.                 /* Add frequency envelope generator */
  333.                 ListNode->LFOFrequencyEnvelope = NewEnvelopeStateRecord(
  334.                     GetLFOSpecFrequencyEnvelope(OneLFOSpec),Accent1,Accent2,Accent3,Accent4,
  335.                     FrequencyHertz,FrequencyScaling,HurryUp,TicksPerSecond,&PreOriginTime);
  336.                 if (ListNode->LFOFrequencyEnvelope == NIL)
  337.                     {
  338.                      FailurePoint2:
  339.                         ListNode->Next = LFOOneStateFreeList;
  340.                         LFOOneStateFreeList = ListNode;
  341.                         goto FailurePoint1;
  342.                     }
  343.                 if (PreOriginTime > MaxPreOrigin)
  344.                     {
  345.                         MaxPreOrigin = PreOriginTime;
  346.                     }
  347.                 /* determine what mode to use and calculate amplitude */
  348.                 AmplitudeFactor = AmplitudeScaling;
  349.                 switch (ModulationMode)
  350.                     {
  351.                         default:
  352.                             EXECUTE(PRERR(ForceAbort,"NewLFOGenerator:  bad modulation mode"));
  353.                             break;
  354.                         case eLFOArithAdditive:
  355.                             ListNode->ModulateLinear = True;
  356.                             AmplitudeFactor = AmplitudeFactor * VolumeScalingFactor;
  357.                             break;
  358.                         case eLFOArithGeometric:
  359.                             ListNode->ModulateLinear = False;
  360.                             break;
  361.                         case eLFOArithDefault:
  362.                             switch (LFOSpecGetAddingMode(OneLFOSpec))
  363.                                 {
  364.                                     default:
  365.                                         EXECUTE(PRERR(ForceAbort,
  366.                                             "NewLFOGenerator:  bad value from LFOSpecGetAddingMode"));
  367.                                         break;
  368.                                     case eLFOArithmetic:
  369.                                         ListNode->ModulateLinear = True;
  370.                                         AmplitudeFactor = AmplitudeFactor * VolumeScalingFactor;
  371.                                         break;
  372.                                     case eLFOGeometric:
  373.                                         ListNode->ModulateLinear = False;
  374.                                         break;
  375.                                 }
  376.                             break;
  377.                     }
  378.                 /* add the amplitude envelope generator */
  379.                 ListNode->LFOAmplitudeEnvelope = NewEnvelopeStateRecord(
  380.                     GetLFOSpecAmplitudeEnvelope(OneLFOSpec),Accent1,Accent2,Accent3,Accent4,
  381.                     FrequencyHertz,AmplitudeFactor,HurryUp,TicksPerSecond,&PreOriginTime);
  382.                 if (ListNode->LFOAmplitudeEnvelope == NIL)
  383.                     {
  384.                      FailurePoint3:
  385.                         DisposeEnvelopeStateRecord(ListNode->LFOFrequencyEnvelope);
  386.                         goto FailurePoint2;
  387.                     }
  388.                 if (PreOriginTime > MaxPreOrigin)
  389.                     {
  390.                         MaxPreOrigin = PreOriginTime;
  391.                     }
  392.                 /* determine what function to use */
  393.                 ListNode->Operator = LFOSpecGetOscillatorType(OneLFOSpec);
  394.                 switch (ListNode->Operator)
  395.                     {
  396.                         default:
  397.                             EXECUTE(PRERR(ForceAbort,"NewLFOGenerator:  bad oscillator type"));
  398.                             break;
  399.                         case eLFOConstant1:
  400.                             switch (LFOSpecGetModulationMode(OneLFOSpec))
  401.                                 {
  402.                                     default:
  403.                                         EXECUTE(PRERR(ForceAbort,"NewLFOGenerator:  bad modulation type"));
  404.                                         break;
  405.                                     case eLFOAdditive:
  406.                                         ListNode->GenFunction = &AddConst;
  407.                                         break;
  408.                                     case eLFOMultiplicative:
  409.                                         ListNode->GenFunction = &MultConst;
  410.                                         break;
  411.                                     case eLFOInverseMultiplicative:
  412.                                         ListNode->GenFunction = &InvMultConst;
  413.                                 }
  414.                             break;
  415.                         case eLFOSignedSine:
  416.                             switch (LFOSpecGetModulationMode(OneLFOSpec))
  417.                                 {
  418.                                     default:
  419.                                         EXECUTE(PRERR(ForceAbort,"NewLFOGenerator:  bad modulation type"));
  420.                                         break;
  421.                                     case eLFOAdditive:
  422.                                         ListNode->GenFunction = &AddSignSine;
  423.                                         break;
  424.                                     case eLFOMultiplicative:
  425.                                         ListNode->GenFunction = &MultSignSine;
  426.                                         break;
  427.                                     case eLFOInverseMultiplicative:
  428.                                         ListNode->GenFunction = &InvMultSignSine;
  429.                                 }
  430.                             break;
  431.                         case eLFOPositiveSine:
  432.                             switch (LFOSpecGetModulationMode(OneLFOSpec))
  433.                                 {
  434.                                     default:
  435.                                         EXECUTE(PRERR(ForceAbort,"NewLFOGenerator:  bad modulation type"));
  436.                                         break;
  437.                                     case eLFOAdditive:
  438.                                         ListNode->GenFunction = &AddPosSine;
  439.                                         break;
  440.                                     case eLFOMultiplicative:
  441.                                         ListNode->GenFunction = &MultPosSine;
  442.                                         break;
  443.                                     case eLFOInverseMultiplicative:
  444.                                         ListNode->GenFunction = &InvMultPosSine;
  445.                                 }
  446.                             break;
  447.                         case eLFOSignedTriangle:
  448.                             switch (LFOSpecGetModulationMode(OneLFOSpec))
  449.                                 {
  450.                                     default:
  451.                                         EXECUTE(PRERR(ForceAbort,"NewLFOGenerator:  bad modulation type"));
  452.                                         break;
  453.                                     case eLFOAdditive:
  454.                                         ListNode->GenFunction = &AddSignTriangle;
  455.                                         break;
  456.                                     case eLFOMultiplicative:
  457.                                         ListNode->GenFunction = &MultSignTriangle;
  458.                                         break;
  459.                                     case eLFOInverseMultiplicative:
  460.                                         ListNode->GenFunction = &InvMultSignTriangle;
  461.                                 }
  462.                             break;
  463.                         case eLFOPositiveTriangle:
  464.                             switch (LFOSpecGetModulationMode(OneLFOSpec))
  465.                                 {
  466.                                     default:
  467.                                         EXECUTE(PRERR(ForceAbort,"NewLFOGenerator:  bad modulation type"));
  468.                                         break;
  469.                                     case eLFOAdditive:
  470.                                         ListNode->GenFunction = &AddPosTriangle;
  471.                                         break;
  472.                                     case eLFOMultiplicative:
  473.                                         ListNode->GenFunction = &MultPosTriangle;
  474.                                         break;
  475.                                     case eLFOInverseMultiplicative:
  476.                                         ListNode->GenFunction = &InvMultPosTriangle;
  477.                                 }
  478.                             break;
  479.                         case eLFOSignedSquare:
  480.                             switch (LFOSpecGetModulationMode(OneLFOSpec))
  481.                                 {
  482.                                     default:
  483.                                         EXECUTE(PRERR(ForceAbort,"NewLFOGenerator:  bad modulation type"));
  484.                                         break;
  485.                                     case eLFOAdditive:
  486.                                         ListNode->GenFunction = &AddSignSquare;
  487.                                         break;
  488.                                     case eLFOMultiplicative:
  489.                                         ListNode->GenFunction = &MultSignSquare;
  490.                                         break;
  491.                                     case eLFOInverseMultiplicative:
  492.                                         ListNode->GenFunction = &InvMultSignSquare;
  493.                                 }
  494.                             break;
  495.                         case eLFOPositiveSquare:
  496.                             switch (LFOSpecGetModulationMode(OneLFOSpec))
  497.                                 {
  498.                                     default:
  499.                                         EXECUTE(PRERR(ForceAbort,"NewLFOGenerator:  bad modulation type"));
  500.                                         break;
  501.                                     case eLFOAdditive:
  502.                                         ListNode->GenFunction = &AddPosSquare;
  503.                                         break;
  504.                                     case eLFOMultiplicative:
  505.                                         ListNode->GenFunction = &MultPosSquare;
  506.                                         break;
  507.                                     case eLFOInverseMultiplicative:
  508.                                         ListNode->GenFunction = &InvMultPosSquare;
  509.                                 }
  510.                             break;
  511.                         case eLFOSignedRamp:
  512.                             switch (LFOSpecGetModulationMode(OneLFOSpec))
  513.                                 {
  514.                                     default:
  515.                                         EXECUTE(PRERR(ForceAbort,"NewLFOGenerator:  bad modulation type"));
  516.                                         break;
  517.                                     case eLFOAdditive:
  518.                                         ListNode->GenFunction = &AddSignRamp;
  519.                                         break;
  520.                                     case eLFOMultiplicative:
  521.                                         ListNode->GenFunction = &MultSignRamp;
  522.                                         break;
  523.                                     case eLFOInverseMultiplicative:
  524.                                         ListNode->GenFunction = &InvMultSignRamp;
  525.                                 }
  526.                             break;
  527.                         case eLFOPositiveRamp:
  528.                             switch (LFOSpecGetModulationMode(OneLFOSpec))
  529.                                 {
  530.                                     default:
  531.                                         EXECUTE(PRERR(ForceAbort,"NewLFOGenerator:  bad modulation type"));
  532.                                         break;
  533.                                     case eLFOAdditive:
  534.                                         ListNode->GenFunction = &AddPosRamp;
  535.                                         break;
  536.                                     case eLFOMultiplicative:
  537.                                         ListNode->GenFunction = &MultPosRamp;
  538.                                         break;
  539.                                     case eLFOInverseMultiplicative:
  540.                                         ListNode->GenFunction = &InvMultPosRamp;
  541.                                 }
  542.                             break;
  543.                         case eLFOSignedLinearFuzz:
  544.                             switch (LFOSpecGetModulationMode(OneLFOSpec))
  545.                                 {
  546.                                     default:
  547.                                         EXECUTE(PRERR(ForceAbort,"NewLFOGenerator:  bad modulation type"));
  548.                                         break;
  549.                                     case eLFOAdditive:
  550.                                         ListNode->GenFunction = &AddSignFuzz;
  551.                                         break;
  552.                                     case eLFOMultiplicative:
  553.                                         ListNode->GenFunction = &MultSignFuzz;
  554.                                         break;
  555.                                     case eLFOInverseMultiplicative:
  556.                                         ListNode->GenFunction = &InvMultSignFuzz;
  557.                                 }
  558.                             break;
  559.                         case eLFOPositiveLinearFuzz:
  560.                             switch (LFOSpecGetModulationMode(OneLFOSpec))
  561.                                 {
  562.                                     default:
  563.                                         EXECUTE(PRERR(ForceAbort,"NewLFOGenerator:  bad modulation type"));
  564.                                         break;
  565.                                     case eLFOAdditive:
  566.                                         ListNode->GenFunction = &AddPosFuzz;
  567.                                         break;
  568.                                     case eLFOMultiplicative:
  569.                                         ListNode->GenFunction = &MultPosFuzz;
  570.                                         break;
  571.                                     case eLFOInverseMultiplicative:
  572.                                         ListNode->GenFunction = &InvMultPosFuzz;
  573.                                 }
  574.                             break;
  575.                         case eLFOWaveTable:
  576.                             switch (LFOSpecGetModulationMode(OneLFOSpec))
  577.                                 {
  578.                                     default:
  579.                                         EXECUTE(PRERR(ForceAbort,"NewLFOGenerator:  bad modulation type"));
  580.                                         break;
  581.                                     case eLFOAdditive:
  582.                                         ListNode->GenFunction = &AddWaveTable;
  583.                                         break;
  584.                                     case eLFOMultiplicative:
  585.                                         ListNode->GenFunction = &MultWaveTable;
  586.                                         break;
  587.                                     case eLFOInverseMultiplicative:
  588.                                         ListNode->GenFunction = &InvMultWaveTable;
  589.                                 }
  590.                             ListNode->WaveTableSourceSelector = NewMultisampleWaveTable(
  591.                                 GetLFOSpecSampleSelector(OneLFOSpec));
  592.                             if (ListNode->WaveTableSourceSelector == NIL)
  593.                                 {
  594.                                  FailurePoint4:
  595.                                     if (ListNode->Operator == eLFOWaveTable)
  596.                                         {
  597.                                             DisposeEnvelopeStateRecord(ListNode->LFOAmplitudeEnvelope);
  598.                                         }
  599.                                     goto FailurePoint3;
  600.                                 }
  601.                             ListNode->WaveTableWasDefined = GetMultisampleReferenceWaveTable(
  602.                                 ListNode->WaveTableSourceSelector,FreqForMultisampling,
  603.                                 &(ListNode->WaveTableMatrix),&(ListNode->FramesPerTable),
  604.                                 &(ListNode->NumberOfTables),&(ListNode->TableNumBits));
  605.                             ListNode->WaveTableIndexEnvelope = NewEnvelopeStateRecord(
  606.                                 GetLFOSpecWaveTableIndexEnvelope(OneLFOSpec),Accent1,Accent2,Accent3,
  607.                                 Accent4,FrequencyHertz,AmplitudeFactor,HurryUp,TicksPerSecond,
  608.                                 &PreOriginTime);
  609.                             if (ListNode->WaveTableIndexEnvelope == NIL)
  610.                                 {
  611.                                  FailurePoint5:
  612.                                     if (ListNode->Operator == eLFOWaveTable)
  613.                                         {
  614.                                             DisposeMultisample(ListNode->WaveTableSourceSelector);
  615.                                         }
  616.                                     goto FailurePoint4;
  617.                                 }
  618.                             if (PreOriginTime > MaxPreOrigin)
  619.                                 {
  620.                                     MaxPreOrigin = PreOriginTime;
  621.                                 }
  622.                             break;
  623.                     }
  624.                 /* link it in */
  625.                 ListNode->Next = NIL;
  626.                 if (ListTail != NIL)
  627.                     {
  628.                         ListTail->Next = ListNode;
  629.                     }
  630.                  else
  631.                     {
  632.                         LFOGen->LFOList = ListNode;
  633.                     }
  634.                 ListTail = ListNode;
  635.             }
  636.  
  637.         *MaxPreOriginTime = MaxPreOrigin;
  638.         return LFOGen;
  639.     }
  640.  
  641.  
  642. /* fix up the origin time so that envelopes start at the proper times */
  643. void                                LFOGeneratorFixEnvelopeOrigins(LFOGenRec* LFOGen,
  644.                                             long ActualPreOriginTime)
  645.     {
  646.         LFOOneStateRec*        Scan;
  647.  
  648.         CheckPtrExistence(LFOGen);
  649.         ValidateLFOGen(LFOGen);
  650.  
  651.         Scan = LFOGen->LFOList;
  652.         while (Scan != NIL)
  653.             {
  654.                 ValidateLFOOneState(Scan);
  655.                 EnvelopeStateFixUpInitialDelay(Scan->LFOAmplitudeEnvelope,ActualPreOriginTime);
  656.                 EnvelopeStateFixUpInitialDelay(Scan->LFOFrequencyEnvelope,ActualPreOriginTime);
  657.                 if (Scan->Operator == eLFOWaveTable)
  658.                     {
  659.                         EnvelopeStateFixUpInitialDelay(Scan->WaveTableIndexEnvelope,
  660.                             ActualPreOriginTime);
  661.                     }
  662.                 Scan = Scan->Next;
  663.             }
  664.     }
  665.  
  666.  
  667. /* this function computes one LFO cycle and returns the value from the LFO generator. */
  668. /* it should be called on the envelope clock. */
  669. FastFixedType                LFOGenUpdateCycle(LFOGenRec* LFOGen, FastFixedType OriginalValue)
  670.     {
  671.         LFOOneStateRec*        Scan;
  672.  
  673.         CheckPtrExistence(LFOGen);
  674.         ValidateLFOGen(LFOGen);
  675.  
  676.         Scan = LFOGen->LFOList;
  677.         if (Scan != NIL)
  678.             {
  679.                 float                            Iterator;
  680.  
  681.                 Iterator = FastFixed2Float(OriginalValue);
  682.                 while (Scan != NIL)
  683.                     {
  684.                         /* perform the calculations */
  685.                         if (Scan->ModulateLinear)
  686.                             {
  687.                                 Iterator = (*Scan->GenFunction)(Scan,FastFixed2Float(Scan->CurrentPhase),
  688.                                     Iterator,FastFixed2Float(EnvelopeUpdate(Scan->LFOAmplitudeEnvelope)));
  689.                             }
  690.                          else
  691.                             {
  692.                                 MyBoolean                    Sign;
  693.  
  694.                                 Sign = (Iterator < 0);
  695.                                 if (Sign)
  696.                                     {
  697.                                         Iterator = - Iterator;
  698.                                     }
  699.                                 if (Iterator != 0)
  700.                                     {
  701.                                         /* the LOG2 is to normalize the values, so that 1/12 will */
  702.                                         /* be 1 halfstep */
  703.                                         Iterator = (float)FEXP((float)LOG2 * (*Scan->GenFunction)(Scan,
  704.                                             FastFixed2Float(Scan->CurrentPhase),(float)FLN(Iterator)
  705.                                             / (float)LOG2,FastFixed2Float(EnvelopeUpdate(
  706.                                             Scan->LFOAmplitudeEnvelope))));
  707.                                     }
  708.                                 if (Sign)
  709.                                     {
  710.                                         Iterator = - Iterator;
  711.                                     }
  712.                             }
  713.                         Scan->CurrentPhase = (Scan->CurrentPhase
  714.                             + FastFixedTimesFastFixedToFastFixed(LFOGen->CorrectionFactor,
  715.                             EnvelopeUpdate(Scan->LFOFrequencyEnvelope)))
  716.                             & ((1L << FASTFIXEDPRECISION) - 1);
  717.                         /* go to next one */
  718.                         Scan = Scan->Next;
  719.                     }
  720.                 return Double2FastFixed(Iterator);
  721.             }
  722.          else
  723.             {
  724.                 return OriginalValue;
  725.             }
  726.     }
  727.  
  728.  
  729. /* pass the key-up impulse on to the envelopes contained inside */
  730. void                                LFOGeneratorKeyUpSustain1(LFOGenRec* LFOGen)
  731.     {
  732.         LFOOneStateRec*        Scan;
  733.  
  734.         CheckPtrExistence(LFOGen);
  735.         ValidateLFOGen(LFOGen);
  736.  
  737.         Scan = LFOGen->LFOList;
  738.         while (Scan != NIL)
  739.             {
  740.                 EnvelopeKeyUpSustain1(Scan->LFOAmplitudeEnvelope);
  741.                 EnvelopeKeyUpSustain1(Scan->LFOFrequencyEnvelope);
  742.                 if (Scan->Operator == eLFOWaveTable)
  743.                     {
  744.                         EnvelopeKeyUpSustain1(Scan->WaveTableIndexEnvelope);
  745.                     }
  746.                 Scan = Scan->Next;
  747.             }
  748.     }
  749.  
  750.  
  751. /* pass the key-up impulse on to the envelopes contained inside */
  752. void                                LFOGeneratorKeyUpSustain2(LFOGenRec* LFOGen)
  753.     {
  754.         LFOOneStateRec*        Scan;
  755.  
  756.         CheckPtrExistence(LFOGen);
  757.         ValidateLFOGen(LFOGen);
  758.  
  759.         Scan = LFOGen->LFOList;
  760.         while (Scan != NIL)
  761.             {
  762.                 EnvelopeKeyUpSustain2(Scan->LFOAmplitudeEnvelope);
  763.                 EnvelopeKeyUpSustain2(Scan->LFOFrequencyEnvelope);
  764.                 if (Scan->Operator == eLFOWaveTable)
  765.                     {
  766.                         EnvelopeKeyUpSustain2(Scan->WaveTableIndexEnvelope);
  767.                     }
  768.                 Scan = Scan->Next;
  769.             }
  770.     }
  771.  
  772.  
  773. /* pass the key-up impulse on to the envelopes contained inside */
  774. void                                LFOGeneratorKeyUpSustain3(LFOGenRec* LFOGen)
  775.     {
  776.         LFOOneStateRec*        Scan;
  777.  
  778.         CheckPtrExistence(LFOGen);
  779.         ValidateLFOGen(LFOGen);
  780.  
  781.         Scan = LFOGen->LFOList;
  782.         while (Scan != NIL)
  783.             {
  784.                 EnvelopeKeyUpSustain3(Scan->LFOAmplitudeEnvelope);
  785.                 EnvelopeKeyUpSustain3(Scan->LFOFrequencyEnvelope);
  786.                 if (Scan->Operator == eLFOWaveTable)
  787.                     {
  788.                         EnvelopeKeyUpSustain3(Scan->WaveTableIndexEnvelope);
  789.                     }
  790.                 Scan = Scan->Next;
  791.             }
  792.     }
  793.  
  794.  
  795. /* retrigger envelopes from the origin point */
  796. void                                LFOGeneratorRetriggerFromOrigin(LFOGenRec* LFOGen, float Accent1,
  797.                                             float Accent2, float Accent3, float Accent4, float FrequencyHertz,
  798.                                             float HurryUp, float TicksPerSecond, float AmplitudeScaling,
  799.                                             float FrequencyScaling, MyBoolean ActuallyRetrigger)
  800.     {
  801.         LFOOneStateRec*        Scan;
  802.  
  803.         CheckPtrExistence(LFOGen);
  804.         ValidateLFOGen(LFOGen);
  805.  
  806.         Scan = LFOGen->LFOList;
  807.         while (Scan != NIL)
  808.             {
  809.                 EnvelopeRetriggerFromOrigin(Scan->LFOAmplitudeEnvelope,Accent1,Accent2,
  810.                     Accent3,Accent4,FrequencyHertz,AmplitudeScaling,HurryUp,
  811.                     LFOGen->EnvelopeTicksPerSecond,ActuallyRetrigger);
  812.                 EnvelopeRetriggerFromOrigin(Scan->LFOFrequencyEnvelope,Accent1,Accent2,
  813.                     Accent3,Accent4,FrequencyHertz,FrequencyScaling,HurryUp,
  814.                     LFOGen->EnvelopeTicksPerSecond,ActuallyRetrigger);
  815.                 if (Scan->Operator == eLFOWaveTable)
  816.                     {
  817.                         EnvelopeRetriggerFromOrigin(Scan->WaveTableIndexEnvelope,Accent1,Accent2,
  818.                             Accent3,Accent4,FrequencyHertz,FrequencyScaling,HurryUp,
  819.                             LFOGen->EnvelopeTicksPerSecond,ActuallyRetrigger);
  820.                     }
  821.                 Scan = Scan->Next;
  822.             }
  823.     }
  824.  
  825.  
  826. /* dispose the LFO generator */
  827. void                                DisposeLFOGenerator(LFOGenRec* LFOGen)
  828.     {
  829.         LFOOneStateRec*        StateScan;
  830.  
  831.         CheckPtrExistence(LFOGen);
  832.         ValidateLFOGen(LFOGen);
  833.  
  834.         StateScan = LFOGen->LFOList;
  835.  
  836.         /* dispose of the master record */
  837.         LFOGen->GarbageLink = LFOGenFreeList;
  838.         LFOGenFreeList = LFOGen;
  839.  
  840.         /* dispose of each element */
  841.         while (StateScan != NIL)
  842.             {
  843.                 LFOOneStateRec*        Temp;
  844.  
  845.                 ValidateLFOOneState(StateScan);
  846.                 if (StateScan->Operator == eLFOWaveTable)
  847.                     {
  848.                         DisposeMultisample(StateScan->WaveTableSourceSelector);
  849.                         DisposeEnvelopeStateRecord(StateScan->WaveTableIndexEnvelope);
  850.                     }
  851.                 DisposeEnvelopeStateRecord(StateScan->LFOAmplitudeEnvelope);
  852.                 DisposeEnvelopeStateRecord(StateScan->LFOFrequencyEnvelope);
  853.                 Temp = StateScan;
  854.                 StateScan = StateScan->Next;
  855.                 Temp->Next = LFOOneStateFreeList;
  856.                 LFOOneStateFreeList = Temp;
  857.             }
  858.     }
  859.  
  860.  
  861. static float                        AddConst(LFOOneStateRec* State, float Phase,
  862.                                                     float OriginalValue, float Amplitude)
  863.     {
  864.         return OriginalValue + Amplitude;
  865.     }
  866.  
  867.  
  868. static float                        AddSignSine(LFOOneStateRec* State, float Phase,
  869.                                                     float OriginalValue, float Amplitude)
  870.     {
  871.         return OriginalValue + Amplitude * FSIN(Phase * TWOPI);
  872.     }
  873.  
  874.  
  875. static float                        AddPosSine(LFOOneStateRec* State, float Phase,
  876.                                                     float OriginalValue, float Amplitude)
  877.     {
  878.         return OriginalValue + Amplitude * (1 + 0.5 * FSIN(Phase * TWOPI));
  879.     }
  880.  
  881.  
  882. static float                        AddSignTriangle(LFOOneStateRec* State, float Phase,
  883.                                                     float OriginalValue, float Amplitude)
  884.     {
  885.         if (Phase < 0.25)
  886.             {
  887.             }
  888.         else if (Phase < 0.75)
  889.             {
  890.                 Phase = 0.5 - Phase;
  891.             }
  892.         else
  893.             {
  894.                 Phase = Phase - 1;
  895.             }
  896.         return OriginalValue + Phase * 4 * Amplitude;
  897.     }
  898.  
  899.  
  900. static float                        AddPosTriangle(LFOOneStateRec* State, float Phase,
  901.                                                     float OriginalValue, float Amplitude)
  902.     {
  903.         if (Phase < 0.25)
  904.             {
  905.             }
  906.         else if (Phase < 0.75)
  907.             {
  908.                 Phase = 0.5 - Phase;
  909.             }
  910.         else
  911.             {
  912.                 Phase = Phase - 1;
  913.             }
  914.         return OriginalValue + Phase * 2 * Amplitude + 0.5;
  915.     }
  916.  
  917.  
  918. static float                        AddSignSquare(LFOOneStateRec* State, float Phase,
  919.                                                     float OriginalValue, float Amplitude)
  920.     {
  921.         if (Phase < 0.5)
  922.             {
  923.                 return OriginalValue + Amplitude;
  924.             }
  925.          else
  926.             {
  927.                 return OriginalValue - Amplitude;
  928.             }
  929.     }
  930.  
  931.  
  932. static float                        AddPosSquare(LFOOneStateRec* State, float Phase,
  933.                                                     float OriginalValue, float Amplitude)
  934.     {
  935.         if (Phase < 0.5)
  936.             {
  937.                 return OriginalValue + Amplitude;
  938.             }
  939.          else
  940.             {
  941.                 return OriginalValue;
  942.             }
  943.     }
  944.  
  945.  
  946. static float                        AddSignRamp(LFOOneStateRec* State, float Phase,
  947.                                                     float OriginalValue, float Amplitude)
  948.     {
  949.         return OriginalValue + Amplitude * (2 * Phase - 1);
  950.     }
  951.  
  952.  
  953. static float                        AddPosRamp(LFOOneStateRec* State, float Phase,
  954.                                                     float OriginalValue, float Amplitude)
  955.     {
  956.         return OriginalValue + Amplitude * Phase;
  957.     }
  958.  
  959.  
  960. static float                        AddSignFuzz(LFOOneStateRec* State, float Phase,
  961.                                                     float OriginalValue, float Amplitude)
  962.     {
  963.         long                                    OldSeed;
  964.         float                                    ReturnValue;
  965.  
  966.         OldSeed = SetParkAndMillerRandomSeed(RandomSeed);
  967.         ReturnValue = (1 - (((float)ParkAndMillerRandom() - PARKANDMILLERMINIMUM)
  968.             / (PARKANDMILLERMAXIMUM - PARKANDMILLERMINIMUM - 1) * Amplitude * 2))
  969.             + OriginalValue;
  970.         RandomSeed = SetParkAndMillerRandomSeed(OldSeed);
  971.         return ReturnValue;
  972.     }
  973.  
  974.  
  975. static float                        AddPosFuzz(LFOOneStateRec* State, float Phase,
  976.                                                     float OriginalValue, float Amplitude)
  977.     {
  978.         long                                    OldSeed;
  979.         float                                    ReturnValue;
  980.  
  981.         OldSeed = SetParkAndMillerRandomSeed(RandomSeed);
  982.         ReturnValue = (((float)ParkAndMillerRandom() - PARKANDMILLERMINIMUM)
  983.             / (PARKANDMILLERMAXIMUM - PARKANDMILLERMINIMUM - 1) * Amplitude)
  984.             + OriginalValue;
  985.         RandomSeed = SetParkAndMillerRandomSeed(OldSeed);
  986.         return ReturnValue;
  987.     }
  988.  
  989.  
  990. static float                        MultConst(LFOOneStateRec* State, float Phase,
  991.                                                     float OriginalValue, float Amplitude)
  992.     {
  993.         return OriginalValue * Amplitude;
  994.     }
  995.  
  996.  
  997. static float                        MultSignSine(LFOOneStateRec* State, float Phase,
  998.                                                     float OriginalValue, float Amplitude)
  999.     {
  1000.         return OriginalValue * Amplitude * FSIN(Phase * TWOPI);
  1001.     }
  1002.  
  1003.  
  1004. static float                        MultPosSine(LFOOneStateRec* State, float Phase,
  1005.                                                     float OriginalValue, float Amplitude)
  1006.     {
  1007.         return OriginalValue * Amplitude * (1 + 0.5 * FSIN(Phase * TWOPI));
  1008.     }
  1009.  
  1010.  
  1011. static float                        MultSignTriangle(LFOOneStateRec* State, float Phase,
  1012.                                                     float OriginalValue, float Amplitude)
  1013.     {
  1014.         if (Phase < 0.25)
  1015.             {
  1016.             }
  1017.         else if (Phase < 0.75)
  1018.             {
  1019.                 Phase = 0.5 - Phase;
  1020.             }
  1021.         else
  1022.             {
  1023.                 Phase = Phase - 1;
  1024.             }
  1025.         return OriginalValue * Phase * 4 * Amplitude;
  1026.     }
  1027.  
  1028.  
  1029. static float                        MultPosTriangle(LFOOneStateRec* State, float Phase,
  1030.                                                     float OriginalValue, float Amplitude)
  1031.     {
  1032.         if (Phase < 0.25)
  1033.             {
  1034.             }
  1035.         else if (Phase < 0.75)
  1036.             {
  1037.                 Phase = 0.5 - Phase;
  1038.             }
  1039.         else
  1040.             {
  1041.                 Phase = Phase - 1;
  1042.             }
  1043.         return OriginalValue * Phase * 2 * Amplitude + 0.5;
  1044.     }
  1045.  
  1046.  
  1047. static float                        MultSignSquare(LFOOneStateRec* State, float Phase,
  1048.                                                     float OriginalValue, float Amplitude)
  1049.     {
  1050.         if (Phase < 0.5)
  1051.             {
  1052.                 return OriginalValue * Amplitude;
  1053.             }
  1054.          else
  1055.             {
  1056.                 return OriginalValue * - Amplitude;
  1057.             }
  1058.     }
  1059.  
  1060.  
  1061. static float                        MultPosSquare(LFOOneStateRec* State, float Phase,
  1062.                                                     float OriginalValue, float Amplitude)
  1063.     {
  1064.         if (Phase < 0.5)
  1065.             {
  1066.                 return OriginalValue * Amplitude;
  1067.             }
  1068.          else
  1069.             {
  1070.                 return 0;
  1071.             }
  1072.     }
  1073.  
  1074.  
  1075. static float                        MultSignRamp(LFOOneStateRec* State, float Phase,
  1076.                                                     float OriginalValue, float Amplitude)
  1077.     {
  1078.         return OriginalValue * Amplitude * (2 * Phase - 1);
  1079.     }
  1080.  
  1081.  
  1082. static float                        MultPosRamp(LFOOneStateRec* State, float Phase,
  1083.                                                     float OriginalValue, float Amplitude)
  1084.     {
  1085.         return OriginalValue * Amplitude * Phase;
  1086.     }
  1087.  
  1088.  
  1089. static float                        MultSignFuzz(LFOOneStateRec* State, float Phase,
  1090.                                                     float OriginalValue, float Amplitude)
  1091.     {
  1092.         long                                    OldSeed;
  1093.         float                                    ReturnValue;
  1094.  
  1095.         OldSeed = SetParkAndMillerRandomSeed(RandomSeed);
  1096.         ReturnValue = (1 - (((float)ParkAndMillerRandom() - PARKANDMILLERMINIMUM)
  1097.             / (PARKANDMILLERMAXIMUM - PARKANDMILLERMINIMUM - 1) * Amplitude * 2))
  1098.             * OriginalValue;
  1099.         RandomSeed = SetParkAndMillerRandomSeed(OldSeed);
  1100.         return ReturnValue;
  1101.     }
  1102.  
  1103.  
  1104. static float                        MultPosFuzz(LFOOneStateRec* State, float Phase,
  1105.                                                     float OriginalValue, float Amplitude)
  1106.     {
  1107.         long                                    OldSeed;
  1108.         float                                    ReturnValue;
  1109.  
  1110.         OldSeed = SetParkAndMillerRandomSeed(RandomSeed);
  1111.         ReturnValue = (((float)ParkAndMillerRandom() - PARKANDMILLERMINIMUM)
  1112.             / (PARKANDMILLERMAXIMUM - PARKANDMILLERMINIMUM - 1) * Amplitude)
  1113.             * OriginalValue;
  1114.         RandomSeed = SetParkAndMillerRandomSeed(OldSeed);
  1115.         return ReturnValue;
  1116.     }
  1117.  
  1118.  
  1119. static float                        InvMultConst(LFOOneStateRec* State, float Phase,
  1120.                                                     float OriginalValue, float Amplitude)
  1121.     {
  1122.         return OriginalValue * (1 - Amplitude);
  1123.     }
  1124.  
  1125.  
  1126. static float                        InvMultSignSine(LFOOneStateRec* State, float Phase,
  1127.                                                     float OriginalValue, float Amplitude)
  1128.     {
  1129.         return OriginalValue * (1 - Amplitude * FSIN(Phase * TWOPI));
  1130.     }
  1131.  
  1132.  
  1133. static float                        InvMultPosSine(LFOOneStateRec* State, float Phase,
  1134.                                                     float OriginalValue, float Amplitude)
  1135.     {
  1136.         return OriginalValue * (1 - Amplitude * (1 + 0.5 * FSIN(Phase * TWOPI)));
  1137.     }
  1138.  
  1139.  
  1140. static float                        InvMultSignTriangle(LFOOneStateRec* State, float Phase,
  1141.                                                     float OriginalValue, float Amplitude)
  1142.     {
  1143.         if (Phase < 0.25)
  1144.             {
  1145.             }
  1146.         else if (Phase < 0.75)
  1147.             {
  1148.                 Phase = 0.5 - Phase;
  1149.             }
  1150.         else
  1151.             {
  1152.                 Phase = Phase - 1;
  1153.             }
  1154.         return OriginalValue * (1 - Phase * 4 * Amplitude);
  1155.     }
  1156.  
  1157.  
  1158. static float                        InvMultPosTriangle(LFOOneStateRec* State, float Phase,
  1159.                                                     float OriginalValue, float Amplitude)
  1160.     {
  1161.         if (Phase < 0.25)
  1162.             {
  1163.             }
  1164.         else if (Phase < 0.75)
  1165.             {
  1166.                 Phase = 0.5 - Phase;
  1167.             }
  1168.         else
  1169.             {
  1170.                 Phase = Phase - 1;
  1171.             }
  1172.         return OriginalValue * (1 - (Phase * 2 * Amplitude + 0.5));
  1173.     }
  1174.  
  1175.  
  1176. static float                        InvMultSignSquare(LFOOneStateRec* State, float Phase,
  1177.                                                     float OriginalValue, float Amplitude)
  1178.     {
  1179.         if (Phase < 0.5)
  1180.             {
  1181.                 return OriginalValue * (1 - Amplitude);
  1182.             }
  1183.          else
  1184.             {
  1185.                 return OriginalValue * (1 + Amplitude);
  1186.             }
  1187.     }
  1188.  
  1189.  
  1190. static float                        InvMultPosSquare(LFOOneStateRec* State, float Phase,
  1191.                                                     float OriginalValue, float Amplitude)
  1192.     {
  1193.         if (Phase < 0.5)
  1194.             {
  1195.                 return OriginalValue * (1 - Amplitude);
  1196.             }
  1197.          else
  1198.             {
  1199.                 return OriginalValue;
  1200.             }
  1201.     }
  1202.  
  1203.  
  1204. static float                        InvMultSignRamp(LFOOneStateRec* State, float Phase,
  1205.                                                     float OriginalValue, float Amplitude)
  1206.     {
  1207.         return OriginalValue * (1 - Amplitude * (2 * Phase - 1));
  1208.     }
  1209.  
  1210.  
  1211. static float                        InvMultPosRamp(LFOOneStateRec* State, float Phase,
  1212.                                                     float OriginalValue, float Amplitude)
  1213.     {
  1214.         return OriginalValue * (1 - Amplitude * Phase);
  1215.     }
  1216.  
  1217.  
  1218. static float                        InvMultSignFuzz(LFOOneStateRec* State, float Phase,
  1219.                                                     float OriginalValue, float Amplitude)
  1220.     {
  1221.         long                                    OldSeed;
  1222.         float                                    ReturnValue;
  1223.  
  1224.         OldSeed = SetParkAndMillerRandomSeed(RandomSeed);
  1225.         ReturnValue = /*(1 - (1 -*/(((float)ParkAndMillerRandom() - PARKANDMILLERMINIMUM)
  1226.             / (PARKANDMILLERMAXIMUM - PARKANDMILLERMINIMUM - 1) * Amplitude * 2)/*))*/
  1227.             * OriginalValue;
  1228.         RandomSeed = SetParkAndMillerRandomSeed(OldSeed);
  1229.         return ReturnValue;
  1230.     }
  1231.  
  1232.  
  1233. static float                        InvMultPosFuzz(LFOOneStateRec* State, float Phase,
  1234.                                                     float OriginalValue, float Amplitude)
  1235.     {
  1236.         long                                    OldSeed;
  1237.         float                                    ReturnValue;
  1238.  
  1239.         OldSeed = SetParkAndMillerRandomSeed(RandomSeed);
  1240.         ReturnValue = (1 - (((float)ParkAndMillerRandom() - PARKANDMILLERMINIMUM)
  1241.             / (PARKANDMILLERMAXIMUM - PARKANDMILLERMINIMUM - 1) * Amplitude))
  1242.             * OriginalValue;
  1243.         RandomSeed = SetParkAndMillerRandomSeed(OldSeed);
  1244.         return ReturnValue;
  1245.     }
  1246.  
  1247.  
  1248. static FastFixedType        CalcWaveTableValue(LFOOneStateRec* State, float Phase)
  1249.     {
  1250.         FastFixedType                    Index;
  1251.         LongLongRec                        FrameIndex;
  1252.         signed long                        Final; /* both 16-bit int & largefixedsigned */
  1253.  
  1254.         ERROR(!State->WaveTableWasDefined,PRERR(ForceAbort,
  1255.             "CalcWaveTableValue:  no wave table"));
  1256.  
  1257.         Index = EnvelopeUpdate(State->WaveTableIndexEnvelope);
  1258.         if (Index < 0)
  1259.             {
  1260.                 Index = 0;
  1261.             }
  1262.         else if (Index > Int2FastFixed(State->NumberOfTables - 1))
  1263.             {
  1264.                 Index = Int2FastFixed(State->NumberOfTables - 1);
  1265.             }
  1266.         Double2LongLong(Phase,FrameIndex);
  1267.         if (State->TableNumBits == eSample8bit)
  1268.             {
  1269.                 /* 8-bit */
  1270.                 if (FastFixed2Int(Index) == State->NumberOfTables - 1)
  1271.                     {
  1272.                         /* this is done in case the wave table index is at the maximum, */
  1273.                         /* in which case there is no table+1 to interpolate with. */
  1274.                         signed char*                WaveData;
  1275.  
  1276.                         FastFixedType                LeftWeight;
  1277.                         long                                ArraySubscript;
  1278.                         signed long                    LeftValue;
  1279.                         signed long                    RightValue;
  1280.  
  1281.                         PRNGCHK(State->WaveTableMatrix,&(State->WaveTableMatrix[FastFixed2Int(
  1282.                             Index)]),sizeof(State->WaveTableMatrix[FastFixed2Int(Index)]));
  1283.                         WaveData = (signed char*)(State->WaveTableMatrix[FastFixed2Int(Index)]);
  1284.  
  1285.                         LeftWeight = LongLongLowHalf(FrameIndex) >> (32 - FASTFIXEDPRECISION);
  1286.                         ArraySubscript = LongLongHighHalf(FrameIndex) & (State->FramesPerTable - 1);
  1287.                         /* L+F(R-L) */
  1288.                         LeftValue = ((signed long)WaveData[ArraySubscript]) << 8; /* convert to 16-bit */
  1289.                         RightValue = ((signed long)WaveData[ArraySubscript + 1]) << 8; /* to 16-bit */
  1290.                         Final = LeftValue + ((LeftWeight * (RightValue - LeftValue)) >> 15);
  1291.                     }
  1292.                  else
  1293.                     {
  1294.                         signed char*                WaveData0;
  1295.                         signed char*                WaveData1;
  1296.                         FastFixedType                Wave0Weight;
  1297.  
  1298.                         FastFixedType                LeftWeight;
  1299.                         long                                ArraySubscript;
  1300.                         signed long                    Left0Value;
  1301.                         signed long                    Right0Value;
  1302.                         signed long                    Left1Value;
  1303.                         signed long                    Right1Value;
  1304.                         FastFixedType                Wave0Temp;
  1305.  
  1306.                         PRNGCHK(State->WaveTableMatrix,&(State->WaveTableMatrix[FastFixed2Int(
  1307.                             Index)]),sizeof(State->WaveTableMatrix[FastFixed2Int(Index)]));
  1308.                         WaveData0 = (signed char*)(State->WaveTableMatrix[
  1309.                             FastFixed2Int(Index)]);
  1310.                         PRNGCHK(State->WaveTableMatrix,&(State->WaveTableMatrix[FastFixed2Int(
  1311.                             Index) + 1]),sizeof(State->WaveTableMatrix[FastFixed2Int(Index) + 1]));
  1312.                         WaveData1 = (signed char*)(State->WaveTableMatrix[
  1313.                             FastFixed2Int(Index) + 1]);
  1314.                         Wave0Weight = Index & FASTFIXEDFRACTMASK;
  1315.  
  1316.                         LeftWeight = LongLongLowHalf(FrameIndex) >> (32 - FASTFIXEDPRECISION);
  1317.                         ArraySubscript = LongLongHighHalf(FrameIndex) & (State->FramesPerTable - 1);
  1318.                         /* L+F(R-L) -- applied twice */
  1319.                         Left0Value = ((signed long)WaveData0[ArraySubscript]) << 8; /* convert to 16-bit */
  1320.                         Right0Value = ((signed long)WaveData0[ArraySubscript + 1]) << 8; /* to 16-bit */
  1321.                         Left1Value = ((signed long)WaveData1[ArraySubscript]) << 8; /* convert to 16-bit */
  1322.                         Right1Value = ((signed long)WaveData1[ArraySubscript + 1]) << 8; /* to 16-bit */
  1323.                         Wave0Temp = Left0Value + ((LeftWeight * (Right0Value - Left0Value)) >> 15);
  1324.                         Final = Wave0Temp + ((Wave0Weight * (Left1Value + ((LeftWeight
  1325.                             * (Right1Value - Left1Value)) >> 15) - Wave0Temp)) >> 15);
  1326.                     }
  1327.             }
  1328.          else
  1329.             {
  1330.                 /* 16-bit */
  1331.                 if (FastFixed2Int(Index) == State->NumberOfTables - 1)
  1332.                     {
  1333.                         /* this is done in case the wave table index is at the maximum, */
  1334.                         /* in which case there is no table+1 to interpolate with. */
  1335.                         signed short*                WaveData;
  1336.  
  1337.                         FastFixedType                LeftWeight;
  1338.                         long                                ArraySubscript;
  1339.                         signed long                    LeftValue;
  1340.                         signed long                    RightValue;
  1341.  
  1342.                         PRNGCHK(State->WaveTableMatrix,&(State->WaveTableMatrix[FastFixed2Int(
  1343.                             Index)]),sizeof(State->WaveTableMatrix[FastFixed2Int(Index)]));
  1344.                         WaveData = (signed short*)(State->WaveTableMatrix[FastFixed2Int(Index)]);
  1345.  
  1346.                         LeftWeight = LongLongLowHalf(FrameIndex) >> (32 - FASTFIXEDPRECISION);
  1347.                         ArraySubscript = LongLongHighHalf(FrameIndex) & (State->FramesPerTable - 1);
  1348.                         /* L+F(R-L) */
  1349.                         LeftValue = WaveData[ArraySubscript];
  1350.                         RightValue = WaveData[ArraySubscript + 1];
  1351.                         Final = LeftValue + ((LeftWeight * (RightValue - LeftValue)) >> 15);
  1352.                     }
  1353.                  else
  1354.                     {
  1355.                         signed short*                WaveData0;
  1356.                         signed short*                WaveData1;
  1357.                         FastFixedType                Wave0Weight;
  1358.  
  1359.                         FastFixedType                LeftWeight;
  1360.                         long                                ArraySubscript;
  1361.                         signed long                    Left0Value;
  1362.                         signed long                    Right0Value;
  1363.                         signed long                    Left1Value;
  1364.                         signed long                    Right1Value;
  1365.                         FastFixedType                Wave0Temp;
  1366.  
  1367.                         PRNGCHK(State->WaveTableMatrix,&(State->WaveTableMatrix[FastFixed2Int(
  1368.                             Index)]),sizeof(State->WaveTableMatrix[FastFixed2Int(Index)]));
  1369.                         WaveData0 = (signed short*)(State->WaveTableMatrix[
  1370.                             FastFixed2Int(Index)]);
  1371.                         PRNGCHK(State->WaveTableMatrix,&(State->WaveTableMatrix[FastFixed2Int(
  1372.                             Index) + 1]),sizeof(State->WaveTableMatrix[FastFixed2Int(Index) + 1]));
  1373.                         WaveData1 = (signed short*)(State->WaveTableMatrix[
  1374.                             FastFixed2Int(Index) + 1]);
  1375.                         Wave0Weight = Index & FASTFIXEDFRACTMASK;
  1376.  
  1377.                         LeftWeight = LongLongLowHalf(FrameIndex) >> (32 - FASTFIXEDPRECISION);
  1378.                         ArraySubscript = LongLongHighHalf(FrameIndex) & (State->FramesPerTable - 1);
  1379.                         /* L+F(R-L) -- applied twice */
  1380.                         Left0Value = WaveData0[ArraySubscript];
  1381.                         Right0Value = WaveData0[ArraySubscript + 1];
  1382.                         Left1Value = WaveData1[ArraySubscript];
  1383.                         Right1Value = WaveData1[ArraySubscript + 1];
  1384.                         Wave0Temp = Left0Value + ((LeftWeight * (Right0Value - Left0Value)) >> 15);
  1385.                         Final = Wave0Temp + ((Wave0Weight * (Left1Value + ((LeftWeight
  1386.                             * (Right1Value - Left1Value)) >> 15)) - Wave0Temp) >> 15);
  1387.                     }
  1388.             }
  1389.         return Final;
  1390.     }
  1391.  
  1392.  
  1393. static float                        AddWaveTable(LFOOneStateRec* State, float Phase,
  1394.                                                     float OriginalValue, float Amplitude)
  1395.     {
  1396.         if (State->WaveTableWasDefined)
  1397.             {
  1398.                 return OriginalValue + Amplitude
  1399.                     * ((float)CalcWaveTableValue(State,Phase) / MAX16BIT);
  1400.             }
  1401.          else
  1402.             {
  1403.                 return OriginalValue;
  1404.             }
  1405.     }
  1406.  
  1407.  
  1408. static float                        MultWaveTable(LFOOneStateRec* State, float Phase,
  1409.                                                     float OriginalValue, float Amplitude)
  1410.     {
  1411.         if (State->WaveTableWasDefined)
  1412.             {
  1413.                 return OriginalValue * Amplitude
  1414.                     * ((float)CalcWaveTableValue(State,Phase) / MAX16BIT);
  1415.             }
  1416.          else
  1417.             {
  1418.                 return 0;
  1419.             }
  1420.     }
  1421.  
  1422.  
  1423. static float                        InvMultWaveTable(LFOOneStateRec* State, float Phase,
  1424.                                                     float OriginalValue, float Amplitude)
  1425.     {
  1426.         if (State->WaveTableWasDefined)
  1427.             {
  1428.                 return OriginalValue * (1 - Amplitude
  1429.                     * ((float)CalcWaveTableValue(State,Phase) / MAX16BIT));
  1430.             }
  1431.          else
  1432.             {
  1433.                 return OriginalValue;
  1434.             }
  1435.     }
  1436.